﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FimetContoDeposito.BLL.Objects;
using FimetContoDeposito.DAL;
using GrayParrot.Core;

namespace FimetContoDeposito.BLL.Facades
{
    public class MagazzinoFacade : FacadeBase<MagazzinoFacade>
    {
        FCDContext m_ctx = null;

        public Repository<FCD_Magazzino, Guid> Repo { get; internal set; }


        public MagazzinoFacade()
        {
        }

        public override void Initialize()
        {
            m_ctx = new FCDContext();
            m_ctx.Configuration.LazyLoadingEnabled = false;
            m_ctx.Configuration.ProxyCreationEnabled = false;

            Repo = this.GetRepository<FCD_Magazzino, Guid>(m_ctx);
        }

        public override void Dispose()
        {
            if (m_ctx != null)
            {
                m_ctx.Dispose();

                Repo.Dispose();
            }
        }

        public ReturnValue<bool> Add(FCD_Magazzino item)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>();

            try
            {
                if (item.Id == Guid.Empty)
                {
                    item.Id = Guid.NewGuid();
                }

                this.Repo.Add(item);
                this.Repo.Save();

                retValue.HasValue = true;
                retValue.Value = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<bool> Edit(FCD_Magazzino item)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>();

            try
            {
                this.Repo.Edit(item);
                this.Repo.Save();

                retValue.HasValue = true;
                retValue.Value = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<bool> Delete(FCD_Magazzino item)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>();

            try
            {
                this.Repo.Delete(item);
                this.Repo.Save();

                retValue.HasValue = true;
                retValue.Value = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<FCD_Magazzino> Get(Guid id)
        {
            ReturnValue<FCD_Magazzino> retValue = new ReturnValue<FCD_Magazzino>();

            try
            {
                retValue.Value = this.Repo.Get(id);
                retValue.HasValue = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IQueryable<FCD_Magazzino>> GetAll()
        {
            ReturnValue<IQueryable<FCD_Magazzino>> retValue = new ReturnValue<IQueryable<FCD_Magazzino>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                retValue.Value = this.Repo.GetAll();
                retValue.HasValue = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<FCD_Magazzino> GetCustomerData(Guid idCustomer, Guid idArticolo)
        {
            ReturnValue<FCD_Magazzino> retValue = new ReturnValue<FCD_Magazzino>();
            retValue.Value = null;
            retValue.HasValue = true;

            try
            {
                var objs = from x in m_ctx.FCD_Magazzinoes
                           where x.IdCustomer == idCustomer && x.Articolo == idArticolo
                           select x;

                if (objs.Any())
                {
                    retValue.Value = objs.FirstOrDefault();
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IQueryable<SituazioneMagazzino>> GetSituazioneMagazzino(Guid idCustomer)
        {
            ReturnValue<IQueryable<SituazioneMagazzino>> retValue = new ReturnValue<IQueryable<SituazioneMagazzino>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_Movimentis
                           join d in m_ctx.FCD_MovimentiDettaglios on x.Id equals d.IdMovimento
                           join a in m_ctx.FCD_AnagraficaArticolis on d.Articolo equals a.Id
                           where x.TipoMovimento == 0 && x.Customer == idCustomer && !x.Cancellato && !d.Cancellato
                           select new SituazioneMagazzino()
                           {
                               Id = x.Id,
                               Prenotata = d.Prenotata,
                               IdArticolo = a.Id,
                               Articolo = a.Descrizione,
                               Giacenza = d.QuantitaDisponibile.Value,
                               Foto = a.Foto,
                               DataCancellazione = d.DataCancellazione.Value
                           };

                if (objs.Any())
                {
                    retValue.Value = objs;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<decimal> GetGiacenza(Guid idArticolo)
        {
            ReturnValue<decimal> retValue = new ReturnValue<decimal>(0);

            var objs = from x in m_ctx.FCD_MovimentiDettaglios.Where(c => c.Articolo == idArticolo && !c.Chiuso && !c.Cancellato && c.FCD_Movimenti.TipoMovimento == 0)
                       group x by new { x.Articolo } into articologroup
                       select new { giacenza = articologroup.Sum(a => a.QuantitaDisponibile) };

            if (objs.Any())
            {
                retValue.HasValue = true;
                retValue.Value = objs.FirstOrDefault().giacenza.Value;
            }

            return retValue;
        }

        public ReturnValue<FCD_CalcolaQuantitaReturnModel> GetQuantitaArticolo(Guid idArticolo)
        {
            ReturnValue<FCD_CalcolaQuantitaReturnModel> retValue = new ReturnValue<FCD_CalcolaQuantitaReturnModel>(null);

            var objs = from x in m_ctx.FCD_CalcolaQuantita(idArticolo) select x;

            if (objs.Any())
            {
                retValue.HasValue = true;
                retValue.Value = objs.FirstOrDefault();
            }

            return retValue;
        }
    }
}
